#include <iostream>
//
// Created by Asus on 2025/6/1.
//
using namespace std;

typedef unsigned long long ull;

class Person {
public:
    //非静态成员变量占对象空间
    int mA;
    int mC;
    //静态成员变量不占对象空间
    static int mB;
    //函数也不占对象空间，所有函数共享一个函数实例
    void func() {
        cout << "this:" << (ull)this << endl;
        cout << "mA:" << (ull)&mA << endl;
        cout  << "mA = " << this->mA << endl;
    }
    Person() {
        mA = 0;
    }
    //静态成员函数也不占对象空间
    static void sfunc() {
    }
};

void demo01() {
    // 8     //非静态成员变量占对象空间 int 4 两个int 8
    // int mA;
    // int mC;
    cout << "sizeof(Person) = " << sizeof(Person) << endl;
    Person::sfunc();
    Person p;
    p.func();
    Person p2;
    p2.func();
}

class Person2 {
    public:
    int age;
    Person2(int age) {
        this->age = age;
    }

    Person2 &PersonAddPersion(Person2 p) {
        this->age += p.age;
        return *this;
    }
};

void demo02() {
    Person2 p1(10);
    cout << "p1.age = " << p1.age << endl;
    Person2 p2(20);
    p2.PersonAddPersion(p1).PersonAddPersion(p1).PersonAddPersion(p1);
    cout << "p2.age = " << p2.age << endl;
}

//空指针访问成员函数
class Person3 {
    public:
    int mAge;
    void ShowClassName() {
        cout << "Person3::ShowClassName()" << endl;
    }
    void ShowPersion() {
        if (this == NULL) {
            return;
        }
        cout << "mAge = " << mAge << endl;
    }
};

void demo03() {
    Person3 *p = NULL;
    p->ShowClassName();//空指针，可以调用成员函数
    p->ShowPersion();//但是如果成员函数中用到了this指针，就不可以了
}

class Person4 {
public:
    int m_A;
    mutable int m_B;
    //this指针的本质是一个指针常量，指针的指向不可修改
    //如果想让指针指向的值也不可以修改，需要声明常函数
    void ShowPersion() const {
        //const Type* const pointer;
        //this = NULL; //不能修改指针的指向 Person* const this;
        //this->mA = 100; //但是this指针指向的对象的数据是可以修改的

        //const修饰成员函数，表示指针指向的内存空间的数据不能修改，除了mutable修饰的变量
        this->m_B = 100;
    }

    void MyFunc() const {
        // mA = 10000;
    }

    void func() {
    }
};
//const修饰对象  常对象
void demo04() {
    const Person4 person;//常量对
    cout << "Person4::ShowPersion()" << person.ShowPersion() << endl;
    // person.m_A = 100; //常对象不能修改成员变量的值,但是可以访问
    // person.func(); // 常对象无法调用普通函数
    person.m_B = 200;  //但是常对象可以修改mutable修饰成员变量
    //常对象访问成员函数
    person.MyFunc(); //常对象不能调用const的函数
}

int main() {
    // demo01();
    // demo02();
    demo03();
    return 0;
}
